package com.xebest.web.controller.storehouse;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.xebest.api.util.OpertorLogUtil;
import com.xebest.common.base.controller.BASEMessage;
import com.xebest.common.base.controller.BaseController;
import com.xebest.common.base.controller.BaseResponse;
import com.xebest.common.enums.erp.storehouse.VenStoreNegativeFlagEnum;
import com.xebest.common.enums.erp.storehouse.VenStoreRecordInventoryFlagEnum;
import com.xebest.common.enums.erp.storehouse.VenStoreStatusEnum;
import com.xebest.common.enums.erp.storehouse.VenStoreTypeEnum;
import com.xebest.common.enums.logtype.ErpLogTypeEnum;
import com.xebest.common.util.RequestUtil;
import com.xebest.common.util.XeRedisUtil;
import com.xebest.constant.XeConstans;
import com.xebest.constant.XeRedisKey;
import com.xebest.util.SysSetBeanUtils;
import com.xebest.util.msg.XeVenStoreHouseMsg;
import com.xebest.util.seq.StoreHouseSeqUtil;
import com.xebest.web.form.XeVenStoreInfoForm;
import com.xebest.web.form.XeVenStoreInfoUpdateForm;
import com.xebest.web.model.XeVenStoreInfoEntity;
import com.xebest.web.model.base.XePageInfo;
import com.xebest.web.service.XeVenStoreInfoService;
import com.xebest.web.view.ErpUserInfo;
import com.xebest.web.view.VenStoreRepeatCoverAreaView;
import com.xebest.web.view.XeVenStoreInfoView;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * 仓库
 *
 * @author 杜春静
 */
@RestController
@RequestMapping("storeManager")
public class XeVenStoreInfoController extends BaseController {

    private static final Logger log = LoggerFactory.getLogger(XeVenStoreInfoController.class);

    @Autowired
    private XeVenStoreInfoService xeVenStoreInfoService;

    /**
     * 保存仓库的基本信息
     *
     * @author 杜春静
     */
    @RequestMapping("saveStore")
    public BaseResponse saveStore(@RequestBody @Validated XeVenStoreInfoUpdateForm form, BindingResult bindingResult) {
        log.info("保存仓库基本信息请求参数为：{}" + JSON.toJSONString(form));
        // 验证参数
        if (null == form) {
            return sendAjaxError(BASEMessage.PARAM_ERROR);
        }
        if (bindingResult.hasErrors()) {
            return sendAjaxError(bindingResult.getFieldError().getDefaultMessage());
        }
        //如果是零采仓和整柜仓，必须记录库存，且允许负库存;且没有覆盖区域
        if (VenStoreTypeEnum.ZERO_STORE.getValue().equals(form.getStoreType())
                || VenStoreTypeEnum.ALLOCATE_STORE.getValue().equals(form.getStoreType())) {
            if (VenStoreRecordInventoryFlagEnum.NO.getValue().equals(form.getRecordInventoryFlag())) {
                return sendAjaxError(BASEMessage.PARAM_ERROR);
            }
            if (VenStoreNegativeFlagEnum.NO.getValue().equals(form.getNegativeFlag())) {
                return sendAjaxError(BASEMessage.PARAM_ERROR);
            }

            if (null != form.getCoverAreaArray() && form.getCoverAreaArray().length > 0) {
                return sendAjaxError(BASEMessage.PARAM_ERROR);
            }
        }
        //如果是退货仓，必须记录库存，且不允许负库存;且没有覆盖区域
        if (VenStoreTypeEnum.REJECT_STORE.getValue().equals(form.getStoreType())) {
            if (VenStoreRecordInventoryFlagEnum.NO.getValue().equals(form.getRecordInventoryFlag())) {
                return sendAjaxError(BASEMessage.PARAM_ERROR);
            }
            if (VenStoreNegativeFlagEnum.YES.getValue().equals(form.getNegativeFlag())) {
                return sendAjaxError(BASEMessage.PARAM_ERROR);
            }

            if (null != form.getCoverAreaArray() && form.getCoverAreaArray().length > 0) {
                return sendAjaxError(BASEMessage.PARAM_ERROR);
            }
        }

        //获取用户信息
        ErpUserInfo userInfo = SysSetBeanUtils.getErpUserInfo(super.getErpLoginUserInfo());


        try {
            String operateContent = JSON.toJSONString(form);
            String storeId = StoreHouseSeqUtil.seqUtils.createStoreIdNo(userInfo.getVenSimpleCode().replace("_", ""));
            form.setStoreId(storeId);
            // 输出结果
            Map<String, Object> resultMap = xeVenStoreInfoService.insertStoreInfo(form, userInfo);
            if ("0001".equals(resultMap.get("result").toString())) {
                return sendAjaxError(resultMap.get("coverArea").toString());
            }
            if ("0002".equals(resultMap.get("result").toString())) {
                return sendAjaxError(BASEMessage.PARAM_ERROR);
            }
            this.insertMqLog(null, storeId, operateContent);
            //更新仓库列表缓存
            Map<String, Object> param = new HashMap<>();
            param.put("userCode", userInfo.getUserCode());
            List<Map<String, Object>> listStoreName = xeVenStoreInfoService.listStoreName(param);
            XeRedisUtil.redisUtil.hset(XeRedisKey.XE_ERP_STORE_MAP_KEY,
                    XeConstans.ERP_STORE_PREFIX + userInfo.getUserCode(), JSON.toJSONString(listStoreName));
        } catch (Exception e) {
            log.error("保存仓库: {} 信息出现异常：{}", form.getStoreName(), e);
            return sendAjaxError();
        }
        return sendAjaxOK();
    }

    /**
     * 修改仓库信息
     *
     * @author 杜春静
     */
    @RequestMapping("editStore")
    public BaseResponse editStore(@RequestBody @Validated XeVenStoreInfoUpdateForm form) {
        log.info("修改仓库信息请求参数为：{}", JSON.toJSONString(form));

        //1、验证参数
        if (null == form || null == form.getStoreId()) {
            return sendAjaxError(BASEMessage.PARAM_ERROR);
        }
        //如果是零采仓和整柜仓，必须记录库存，且允许负库存
        if (VenStoreTypeEnum.ZERO_STORE.getValue().equals(form.getStoreType())
                || VenStoreTypeEnum.ALLOCATE_STORE.getValue().equals(form.getStoreType())) {
            if (VenStoreNegativeFlagEnum.NO.getValue().equals(form.getNegativeFlag())) {
                return sendAjaxError(BASEMessage.PARAM_ERROR);
            }
            if (VenStoreRecordInventoryFlagEnum.NO.getValue().equals(form.getRecordInventoryFlag())) {
                return sendAjaxError(BASEMessage.PARAM_ERROR);
            }
            if (null != form.getCoverAreaArray() && form.getCoverAreaArray().length > 0) {
                return sendAjaxError(BASEMessage.PARAM_ERROR);
            }
        }
        //如果是退货仓，必须记录库存，且不允许负库存
        if (VenStoreTypeEnum.REJECT_STORE.getValue().equals(form.getStoreType())) {
            if (VenStoreRecordInventoryFlagEnum.NO.getValue().equals(form.getRecordInventoryFlag())) {
                return sendAjaxError(BASEMessage.PARAM_ERROR);
            }
            if (VenStoreNegativeFlagEnum.YES.getValue().equals(form.getNegativeFlag())) {
                return sendAjaxError(BASEMessage.PARAM_ERROR);
            }

            if (null != form.getCoverAreaArray() && form.getCoverAreaArray().length > 0) {
                return sendAjaxError(BASEMessage.PARAM_ERROR);
            }
        }

        //获取用户登录信息
        ErpUserInfo userInfo = SysSetBeanUtils.getErpUserInfo(super.getErpLoginUserInfo());


        try {
            // 输出结果
            Map<String, Object> resultMap = xeVenStoreInfoService.updateStoreInfo(form, userInfo);

            if ("0001".equals(resultMap.get("result").toString())) {
                return sendAjaxError(resultMap.get("coverArea").toString());
            }
            if ("0002".equals(resultMap.get("result").toString())) {
                return sendAjaxError(BASEMessage.PARAM_ERROR);
            }
            //添加链路监控日志
            String operateContent = JSON.toJSONString(form);
            this.insertMqLog(null, form.getStoreId(), operateContent);
            //更新仓库列表缓存
            Map<String, Object> param = new HashMap<>();
            param.put("userCode", userInfo.getUserCode());
            List<Map<String, Object>> listStoreName = xeVenStoreInfoService.listStoreName(param);
            XeRedisUtil.redisUtil.hset(XeRedisKey.XE_ERP_STORE_MAP_KEY,
                    XeConstans.ERP_STORE_PREFIX + userInfo.getUserCode(), JSON.toJSONString(listStoreName));

        } catch (Exception e) {
            log.error("修改仓库: {},信息异常：{}", form.getStoreId(), e);
            return sendAjaxError();
        }
        return sendAjaxOK();
    }

    /**
     * 根据仓库代码查询仓库信息
     *
     * @author 杜春静
     */
    @RequestMapping(value = "getStoreInfo", method = RequestMethod.POST)
    public BaseResponse queryStoreInfoById(@RequestBody XeVenStoreInfoForm form) {
        log.info("根据仓库代码查询仓库信息请求参数为：{}", JSON.toJSONString(form));
        // 验证参数
        if (null == form || StringUtils.isEmpty(form.getStoreId())) {

            return sendAjaxError(BASEMessage.PARAM_ERROR);

        }
        String storeId = form.getStoreId();
        //获取登录用户信息
        ErpUserInfo userInfo = SysSetBeanUtils.getErpUserInfo(super.getErpLoginUserInfo());

        Map<String, Object> data = new HashMap<>();
        try {
            // 返回结果提参
            XeVenStoreInfoEntity storeInfo = xeVenStoreInfoService.getStoreInfoByMap(storeId, userInfo.getUserCode());

            data.put("storeInfo", storeInfo);
        } catch (Exception e) {
            log.error("根据仓库代码:{},查询仓库信息异常：{}", storeId, e);
            return sendAjaxError();
        }
        return this.sendAjaxOK(data);
    }

    /**
     * 查询仓库与其他仓库重复的覆盖区域
     *
     * @author 杜春静
     */
    @RequestMapping(value = "queryRepeatCoverArea", method = RequestMethod.POST)
    public BaseResponse queryRepeatCoverArea(@RequestBody XeVenStoreInfoForm form) {
        log.info("查询仓库与其他仓库重复的覆盖区域请求参数为：{} ", JSON.toJSONString(form));
        // 验证参数
        if (null == form || StringUtils.isEmpty(form.getStoreId()) || null == form.getCityIds() || 0 == form.getCityIds().length) {

            return sendAjaxError(BASEMessage.PARAM_ERROR);
        }
        String storeId = form.getStoreId();
        String[] cityIds = form.getCityIds();
        Map<String, Object> data = new HashMap<>();
        // 获取用户信息
        ErpUserInfo userInfo = SysSetBeanUtils.getErpUserInfo(super.getErpLoginUserInfo());
        try {
            List<VenStoreRepeatCoverAreaView> coverList = xeVenStoreInfoService.listOtherStoreCoverArea(storeId, cityIds, userInfo.getUserCode());
            data.put("coverList", coverList);
            StringBuffer resultMessage = new StringBuffer();
            for (VenStoreRepeatCoverAreaView coverAreaView : coverList) {
                resultMessage.append("当前仓库覆盖区域" + coverAreaView.getCoverAreaName() + "与" + coverAreaView.getStoreName() + "重复，无法保存，请修改覆盖区域。");
            }
            return this.sendRemoteAjaxError(resultMessage.toString());

        } catch (Exception e) {

            log.error("查询仓库与其他仓库重复的覆盖区域出现异常，异常信息：{}", e);
            return sendAjaxError();
        }
    }

    /**
     * 查询仓库信息列表
     *
     * @author 杜春静
     */
    @RequestMapping("queryStoreInfoList")
    public BaseResponse queryStoreInfoList(@RequestBody XeVenStoreInfoForm form) {
        if (null == form) {
            form = new XeVenStoreInfoForm();
        }
        log.info("查询仓库列表请求参数为：{}", JSON.toJSONString(form));

        // 拼装供应商code
        ErpUserInfo userInfo = SysSetBeanUtils.getErpUserInfo(super.getErpLoginUserInfo());
        String userCode = userInfo.getUserCode();
        form.setUserCode(userCode);
        //封装分页查询数据
        XePageInfo<XeVenStoreInfoView> xePageInfo;
        PageHelper.startPage(form.getPageNum(), form.getPageSize(), true);
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("form", form);
        try {
            List<XeVenStoreInfoView> storeInfoList = this.xeVenStoreInfoService.listByStoreInfoEntity(paramMap);
            xePageInfo = new XePageInfo<XeVenStoreInfoView>(storeInfoList);
            Map<String, Object> map = new HashMap<>();
            map.put("actionList", storeInfoList);
            map.put("xePageInfo", xePageInfo);
            return sendAjaxOK(map);
        } catch (Exception e) {
            log.error("--------------查询仓库列表 异常信息为：{}", e);
            return sendAjaxError();
        }
    }

    /**
     * 启用仓库
     *
     * @author 杜春静
     */
    @RequestMapping(value = "enableStore", method = RequestMethod.POST)
    public BaseResponse enableStore(@RequestBody XeVenStoreInfoForm form) {
        log.info("启用仓库信息请求参数为：{}", JSON.toJSONString(form));

        //验证参数
        if (null == form || null == form.getStoreId() || StringUtils.isEmpty(form.getStoreId())
                || null == form.getStoreStatus() || form.getStoreStatus().equals(0) || form.getStoreStatus().equals(VenStoreStatusEnum.NO.getValue()) || null == form.getStoreType()) {
            return sendAjaxError(BASEMessage.PARAM_ERROR);
        }
        String storeId = form.getStoreId();
        Integer storeStatus = form.getStoreStatus();
        //如果是零采仓、整柜仓、退货仓，不允许进行仓库的状态修改
		/*if(VenStoreTypeEnum.ALLOCATE_STORE.getValue().equals(form.getStoreType())
				|| VenStoreTypeEnum.ZERO_STORE.getValue().equals(form.getStoreType())
				|| VenStoreTypeEnum.REJECT_STORE.getValue().equals(form.getStoreType())){
			return sendAjaxError(XeVenStoreHouseMsg.ZREO_ALLOT_REJECT_ENABLE);
		}*/
        // 获取供应商code
        ErpUserInfo userInfo = SysSetBeanUtils.getErpUserInfo(super.getErpLoginUserInfo());
        String userCode = userInfo.getUserCode();

        try {
            // 输出结果
            Map<String, Object> resultMap = xeVenStoreInfoService.enableOrDisableStore(storeId, storeStatus, userCode);
            if ("0001".equals(resultMap.get("result").toString())) {
                return sendAjaxError(resultMap.get("coverArea").toString());
            }
            if ("0002".equals(resultMap.get("result").toString())) {
                return sendAjaxError(BASEMessage.PARAM_ERROR);
            }

            //添加链路监控日志
            String operateContent = JSON.toJSONString(form);
            this.insertMqLog(null, form.getStoreId(), operateContent);
            //更新仓库列表缓存
            Map<String, Object> param = new HashMap<>();
            param.put("userCode", userInfo.getUserCode());
            List<Map<String, Object>> listStoreName = xeVenStoreInfoService.listStoreName(param);
            XeRedisUtil.redisUtil.hset(XeRedisKey.XE_ERP_STORE_MAP_KEY,
                    XeConstans.ERP_STORE_PREFIX + userInfo.getUserCode(), JSON.toJSONString(listStoreName));
        } catch (Exception e) {
            log.error("启用仓库异常：{}", e);
            return sendAjaxError();
        }
        return sendAjaxOK();
    }

    /**
     * 禁用仓库
     *
     * @author 杜春静
     */
    @RequestMapping(value = "disableStore", method = RequestMethod.POST)
    public BaseResponse disableStore(@RequestBody XeVenStoreInfoForm form) {
        log.info("禁用仓库信息请求参数为：{}", JSON.toJSONString(form));
        String storeId = form.getStoreId();
        Integer storeStatus = form.getStoreStatus();
        //验证参数
        if (null == form || null == form.getStoreId() || StringUtils.isEmpty(form.getStoreId())
                || null == form.getStoreStatus() || form.getStoreStatus().equals(0) || form.getStoreStatus().equals(VenStoreStatusEnum.YES.getValue()) || null == form.getStoreType()) {
            return sendAjaxError(BASEMessage.PARAM_ERROR);
        }
        //如果是零采仓、整柜仓、退货仓，不允许进行仓库的状态修改
        if (VenStoreTypeEnum.ALLOCATE_STORE.getValue().equals(form.getStoreType())
                || VenStoreTypeEnum.ZERO_STORE.getValue().equals(form.getStoreType())
                || VenStoreTypeEnum.REJECT_STORE.getValue().equals(form.getStoreType())) {
            return sendAjaxError(XeVenStoreHouseMsg.ZREO_ALLOT_REJECT_ENABLE);
        }
        // 获取供应商code
        ErpUserInfo userInfo = SysSetBeanUtils.getErpUserInfo(super.getErpLoginUserInfo());
        String userCode = userInfo.getUserCode();

        try {
            // 输出结果
            Map<String, Object> resultMap = xeVenStoreInfoService.enableOrDisableStore(storeId, storeStatus, userCode);
            if ("0001".equals(resultMap.get("result").toString())) {
                return sendAjaxError(resultMap.get("coverArea").toString());
            }
            if ("0002".equals(resultMap.get("result").toString())) {
                return sendAjaxError(BASEMessage.PARAM_ERROR);
            }
            //添加链路监控日志
            String operateContent = JSON.toJSONString(form);
            this.insertMqLog(null, form.getStoreId(), operateContent);
            //更新仓库列表缓存
            Map<String, Object> param = new HashMap<>();
            param.put("userCode", userInfo.getUserCode());
            List<Map<String, Object>> listStoreName = xeVenStoreInfoService.listStoreName(param);
            XeRedisUtil.redisUtil.hset(XeRedisKey.XE_ERP_STORE_MAP_KEY,
                    XeConstans.ERP_STORE_PREFIX + userInfo.getUserCode(), JSON.toJSONString(listStoreName));
        } catch (Exception e) {
            log.error("禁用仓库异常：{}", e);
            return sendAjaxError();
        }
        return sendAjaxOK();
    }

    /**
     * 判断仓库名称是否已经存在
     *
     * @author 杜春静
     */
    @RequestMapping("checkStoreName")
    public BaseResponse checkStoreName(@RequestBody XeVenStoreInfoForm form) {

        log.info("查询仓库名称或仓库编码是否已经存在，请求参数为：" + JSON.toJSONString(form));
        // 验证参数是否合法
        if (null == form || StringUtils.isEmpty(form.getStoreName())) {
            return sendAjaxError(BASEMessage.PARAM_ERROR);
        }
        XeVenStoreInfoEntity entity = new XeVenStoreInfoEntity();
        entity.setStoreName(form.getStoreName());

        //  添加供应商编码
        ErpUserInfo userInfo = SysSetBeanUtils.getErpUserInfo(super.getErpLoginUserInfo());
        entity.setUserCode(userInfo.getUserCode());
        if (!StringUtils.isEmpty(form.getStoreId())) {
            entity.setStoreId(form.getStoreId());
        }

        try {
            Long countStore = this.xeVenStoreInfoService.countByStoreInfo(entity);

            if (null != countStore && countStore > 0) {

                return this.sendRemoteAjaxError(XeVenStoreHouseMsg.STORE_NAME_EXIST);
            }
            return this.sendRemoteAjaxOK();
        } catch (Exception e) {
            log.error("--------------查询仓库名称或仓库编码是否已经存在 异常为{}", e);
            return this.sendRemoteAjaxError(XeVenStoreHouseMsg.STORE_NAME_EXIST);
        }
    }

    /**
     * 获取仓库名称列表信息
     *
     * @author 杜春静
     */
    @RequestMapping("queryStoreNameList")
    public BaseResponse queryStoreNameList(@RequestBody XeVenStoreInfoForm form) {

        log.info("获取仓库名称列表信息，请求参数为{}", JSON.toJSONString(form));
        //设置查询参数
        Map<String, Object> params = new HashMap<>();
        //添加供应商编码
        ErpUserInfo userInfo = SysSetBeanUtils.getErpUserInfo(super.getErpLoginUserInfo());
        params.put("userCode", userInfo.getUserCode());
        params.put("form", form);
        try {

            Map<String, Object> map = new HashMap<>();
            //是否有数据
//			String result =XeRedisUtil.redisUtil.hget(XeRedisKey.XE_ERP_STORE_MAP_KEY, XeConstans.ERP_STORE_PREFIX +userInfo.getUserCode());
//			map.put("actionList", JSONArray.parse(result));
            //如果为空  查询数据库
//			if (null == result) {
            // 输出结果
            List<Map<String, Object>> storeInfoList = this.xeVenStoreInfoService.listStoreName(params);
            map.put("actionList", storeInfoList);
//			}
            return sendAjaxOK(map);
        } catch (Exception e) {
            log.error("--------------获取仓库名称列表信息 异常为{}", e);
            return sendAjaxError();
        }
    }

    /**
     * 添加仓储中心MQ日志
     *
     * @author 杜春静
     */
    private void insertMqLog(String logType, String key, String operatorContent) {
        try {
            String ipAddress = RequestUtil.getClientIpAddress(request);
            if (StringUtils.isBlank(logType)) {
                logType = ErpLogTypeEnum.erpStorage.getValue();
            }
            ErpUserInfo userInfo = SysSetBeanUtils.getErpUserInfo(super.getErpLoginUserInfo());
            String userCode = userInfo.getUserCode();
            log.info("仓储中心MQ日志插入");
            OpertorLogUtil.opertorLog.sendOperatorLogByParam(ipAddress, key, logType, userInfo.getUserName(), operatorContent, userCode);
        } catch (Exception e) {
            log.error("仓储中心MQ日志插入失败,logType={},operatorContent={}", logType, operatorContent);
        }
    }


}
  
